package dao;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import util.Conversion;
import dto.TemplateCategoryDTO;
import dto.TemplateDTO;
import entities.Category;
import entities.Template;
import entities.TemplateCategory;

/**
 * Session Bean implementation class TemplateDAO
 */
@Stateless
public class TemplateDAO implements TemplateDAORemote {

	@PersistenceContext
	EntityManager em;
	Conversion converter = new Conversion();

	/**
	 * Default constructor.
	 */
	public TemplateDAO() {
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public TemplateDTO getTemplateDTOById(int templateID) throws Exception {
		TypedQuery<Template> query = em.createQuery(
				"SELECT t FROM Template t WHERE t.id = :idTemplate",
				Template.class);
		query.setParameter("idTemplate", templateID);
		List<Template> result = query.getResultList();
		if (result.size() > 0)
			try {
				return converter.fromTemplateToTemplateDTO(result.get(0));
			} catch (Exception e) {
				throw new Exception("Could not convert from Template to TemplateDTO!", e);
			}
		return null;
	}
	
	@Override
	public List<TemplateDTO> findAllTemplates() {
		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery<Template> cq = cb.createQuery(Template.class);
		Root<Template> cust = cq.from(Template.class);
		cq.select(cust);
		TypedQuery<Template> q = em.createQuery(cq);
		List<Template> l = q.getResultList();
		List<TemplateDTO> tl = new ArrayList<TemplateDTO>();
		try {
			for (Template t : l) {
				tl.add(converter.fromTemplateToTemplateDTO(t));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return tl;
	}

	@Override
	public int addTemplate(TemplateDTO templateDTO) throws Exception {

		try {
			Template template = converter
					.fromTemplateDTOToTemplate(templateDTO);
			if ((em.find(Template.class, template.getId()) != null)) {
				em.merge(template);
			} else {
				em.persist(template);
			}
			TypedQuery<Template> query = em.createQuery(
					"SELECT t FROM Template t ", Template.class);
			return query.getResultList().get(query.getResultList().size() - 1)
					.getId();
		} catch (Exception e) {
			throw new Exception("Template could not be added!", e);
		}

	}

	@Override
	public void addTempCatToTemplate(int id, List<TemplateCategoryDTO> tcDTO)
			throws Exception {
		Template t = findTemplateById(id);
		Category c;
		if (t != null) {
			List<TemplateCategory> tempCats = new ArrayList<TemplateCategory>();
			for (TemplateCategoryDTO tc : tcDTO) {
				try {
					c = findCategoryById(tc.getCategory().getId());
					tempCats
							.add(converter
									.fromTemplateCategoryDTOtoTemplateCategory(
											tc, t, c));

				} catch (Exception e) {
					throw new Exception("TemplateCategory could not be added!",
							e);
				}
			}

			for (TemplateCategory tc : tempCats) {
				em.persist(tc);
			}
			t.setTemplateCategories(tempCats);
		}
	}

	public Template findTemplateById(int templateID) {
		TypedQuery<Template> query = em.createQuery(
				"SELECT t FROM Template t WHERE t.id = :idTemplate",
				Template.class);
		query.setParameter("idTemplate", templateID);
		List<Template> result = query.getResultList();
		if (result.size() > 0)
			return result.get(0);
		return null;
	}

	public Category findCategoryById(int categoryID) {
		TypedQuery<Category> query = em.createQuery(
				"SELECT c FROM Category c WHERE c.id = :idCateg",
				Category.class);
		query.setParameter("idCateg", categoryID);
		List<Category> result = query.getResultList();
		if (result.size() > 0)
			return result.get(0);
		return null;
	}
}
